package com.heima.article.service.impl;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.article.mapper.ApArticleMapper;
import com.heima.article.service.ApArticleConfigService;
import com.heima.article.service.ApArticleContentService;
import com.heima.article.service.ApArticleService;
import com.heima.article.service.AuthorService;
import com.heima.common.constants.wemedia.WemediaConstants;
import com.heima.common.exception.CustException;
import com.heima.feigns.AdminFeign;
import com.heima.feigns.WemediaFeign;
import com.heima.model.admin.pojos.AdChannel;
import com.heima.model.article.pojos.ApArticle;
import com.heima.model.article.pojos.ApArticleConfig;
import com.heima.model.article.pojos.ApArticleContent;
import com.heima.model.article.pojos.ApAuthor;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.wemedia.pojos.WmNews;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class ApArticleServiceImpl extends ServiceImpl<ApArticleMapper, ApArticle> implements ApArticleService {

    //依赖注入
    @Autowired
    private WemediaFeign wemediaFeign;

    @Autowired
    private AdminFeign adminFeign;

    @Autowired
    private AuthorService authorService;

    @Autowired
    private ApArticleConfigService apArticleConfigService;

    @Autowired
    private ApArticleContentService apArticleContentService;

    /**
     * 发布文章上线
     * @param id
     */
    @GlobalTransactional(rollbackFor = Exception.class,timeoutMills = 300000)
    @Override
    public void publishArticle(Integer id) {
        //1.根据id查询自媒体文章信息
       WmNews wmNews = findWmNews(id);
        //2.使用WmNews信息来封装ApArticle对象
      ApArticle apArticle = parseApArticle(wmNews);
        System.out.println(apArticle);
        //3.保存或者修改apArticle对象
        saveOrUpdateApArticle(apArticle);
        //4.保存关联配置和文章内容
        saveConfigAndContent(apArticle,wmNews);
        //5.TODO 实现页面静态化

        //6.更改WmNews状态，将状态改为9并设置关联的articleId
        updateWmNews(wmNews,apArticle);

        //7.TODO MQ通知es索引库，更新文章索引

    }

    /**
     * 更改WmNews状态，将状态改为9并设置关联的articleId
     * @param wmNews
     * @param apArticle
     */
    private void updateWmNews(WmNews wmNews, ApArticle apArticle) {
        //1.更改WmNews状态
        wmNews.setStatus(WmNews.Status.PUBLISHED.getCode());
        wmNews.setArticleId(apArticle.getId());
        //2.调用远程wemediaFeign更新状态
        ResponseResult result = wemediaFeign.update(wmNews);
        //判断远程调用是否出错
        if (!result.checkCode()){
            CustException.cust(AppHttpCodeEnum.SERVER_ERROR,"远程调用自媒体出错了");
        }

    }

    /**
     * 保存关联配置和文章内容
     * @param apArticle
     * @param wmNews
     */
    private void saveConfigAndContent(ApArticle apArticle, WmNews wmNews) {
        //1.保存关联配置类信息
        ApArticleConfig apArticleConfig = new ApArticleConfig();
        apArticleConfig.setArticleId(apArticle.getId());//文章id
        apArticleConfig.setIsComment(true);//是否允许评论
        apArticleConfig.setIsForward(true);//是否允许转发
        apArticleConfig.setIsDown(false);//是否下架
        apArticleConfig.setIsDelete(false);//是否删除
        apArticleConfigService.save(apArticleConfig);
        //2.保存文章内容信息
        ApArticleContent apArticleContent = new ApArticleContent();
        apArticleContent.setArticleId(wmNews.getArticleId());//文章id
        apArticleContent.setContent(wmNews.getContent());//文章内容
        apArticleContentService.save(apArticleContent);

    }

    /**
     * 保存或者修改apArticle对象
     * @param apArticle
     */
    private void saveOrUpdateApArticle(ApArticle apArticle) {
        //判断文章对象是否为空
        if (apArticle.getId()==null){
            //保存文章
            apArticle.setViews(0);//浏览量
            apArticle.setLikes(0);//点赞量
            apArticle.setComment(0);//评论量
            apArticle.setCollection(0);//收藏量
            this.save(apArticle);
        }else {
            // 删除关联的 文章配置信息  和  文章详情信息
            apArticleConfigService.remove(Wrappers.<ApArticleConfig>lambdaQuery()
                    .eq(ApArticleConfig::getArticleId,apArticle.getId()));

            apArticleContentService.remove(Wrappers.<ApArticleContent>lambdaQuery()
                    .eq(ApArticleContent::getArticleId,apArticle.getId()));
            //修改文章
           this.updateById(apArticle);
        }
    }

    /**
     * 使用WmNews信息来封装ApArticle对象
     * @param wmNews
     * @return
     */
    private ApArticle parseApArticle(WmNews wmNews) {
        //1.创建article对象，将wmnews属性放进去
        ApArticle article = new ApArticle();
        BeanUtils.copyProperties(wmNews,article);
        //2.单独创建articleId字段
        article.setId(wmNews.getArticleId());
        //3.补充其他字段 layout flag
        article.setLayout(wmNews.getType());
        article.setFlag((byte)0);
        //4.获取频道信息
        ResponseResult<AdChannel> result = adminFeign.findById(wmNews.getChannelId());
        if (!result.checkCode()){
            CustException.cust(AppHttpCodeEnum.SERVER_ERROR,"远程频道调用出错");
        }
        //获取查询结果的信息
        AdChannel channel = result.getData();
        //设置频道名称
        article.setChannelName(channel.getName());
        //6.获取作者信息
        ApAuthor author = authorService.getOne(Wrappers.<ApAuthor>lambdaQuery().eq(ApAuthor::getWmUserId, wmNews.getUserId()));
        //设置作者id和姓名
       article.setAuthorId(Long.valueOf(author.getId()));
       article.setAuthorName(author.getName());
       return article;
    }

    /**
     * 根据id查询自媒体文章信息
     * @param id
     * @return
     */
    private WmNews findWmNews(Integer id) {
        //1.参数校验
        if (id==null){
            CustException.cust(AppHttpCodeEnum.PARAM_INVALID,"id无效");
        }
        //2.获取文章信息
        ResponseResult<WmNews> result = wemediaFeign.findById(id);
        //判断远程调用是否成功
        if (!result.checkCode()){
            CustException.cust(AppHttpCodeEnum.SERVER_ERROR,"远程自媒体调用出错");
        }
        //获取结果信息
        WmNews wmNews = result.getData();
        //3.判断文章是否为空
        if (wmNews==null){
            CustException.cust(AppHttpCodeEnum.DATA_NOT_EXIST,"文章不存在");
        }
        //4.判断文章状态是否为4或者8
        if (!wmNews.getStatus().equals(WmNews.Status.ADMIN_SUCCESS.getCode()) && !wmNews.getStatus().equals(WmNews.Status.SUCCESS.getCode())){
            CustException.cust(AppHttpCodeEnum.DATA_NOT_EXIST,"文章状态不是审核通过状态，文章发布失败");
        }

        return wmNews;
    }
}
